home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Converters / Convert_MacPaint / Source / shared.subproj / RCS / NeXTToMacText.m,v < prev    next >
Text File  |  1995-06-12  |  17KB  |  490 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  beta10:1.1;
  5. locks    death:1.2;
  6. comment  @@;
  7.  
  8.  
  9. 1.2
  10. date     93.04.04.23.44.44;  author death;  state Exp;
  11. branches ;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     93.01.10.15.08.29;  author death;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19.  
  20. desc
  21. @@
  22.  
  23.  
  24. 1.2
  25. log
  26. @Sun Apr  4 23:44:44 PDT 1993
  27. @
  28. text
  29. @/*====================================================================
  30. This is the implementation file for the NeXTToMacText class.  Full documentation for this class can be found in the NeXTToMacText.rtf file.  I will not duplicate all that fine information here.
  31.  
  32. NOTE: You may find that text doesn't line up properly unless you use the New Century Schoolbook Roman typeface, since this was created with it.
  33.  
  34. INFORMATION:
  35.     This is $Revision: 1.1 $ of this file
  36.     It was last modifiFed by $Author: death $ on $Date: 93/01/10 15:08:29 $
  37.      $Log:    NeXTToMacText.m,v $
  38. Revision 1.1  93/01/10  15:08:29  death
  39. Sun Jan 10 15:08:29 PST 1993
  40.  
  41. ====================================================================*/
  42.  
  43.  
  44. #import "NeXTToMacText.h"
  45. #import <memory.h>    // for memcpy
  46. #include <strings.h>
  47.  
  48.  
  49. @@implementation NeXTToMacText
  50.  
  51.  
  52. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  53. //    Routine:        init:
  54. //    Parameters:    none
  55. //    Returns:        self
  56. //    Stores:        none
  57. //    Description:
  58. //        This initalizes the object by filling in the convert array that it uses to
  59. //        dictate most of its character conversions.
  60. //    Bugs:
  61. //        Note that we store a null to indicate any characters that can't be
  62. //        converted directly.  Because of this strategy, the null character must be dealt
  63. //        with in this object, though really it is part of the superclass' territory.
  64. //        other more complex implementations (keep a flag with each array entry
  65. //        to indicate if we can convert to it, or keep integers so one can store more than
  66. //        one of 256 values in an entry  might be used to reimplement this if needed.
  67. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  68. - (Instance) init
  69. {
  70.     Integer    counter;
  71.     //
  72.     [super init];
  73.     
  74.     UseCurlyQuotes = NO;
  75.     //
  76.     //    Initialize conversion array with whatever our superclass likes to do.
  77.     //
  78.     for (counter = 0; counter < 256; counter++)
  79.         ConvertArray[counter] = [super     ConvertCharacter: (Character) counter];
  80.     //
  81.     //    We view the world as: we are just like whatever our superclass is, except
  82.     //    that we differ for characters 0,  NL, and anything above 128. =)  So,
  83.     //    modify the table to reflect all of this.  (note: indices are essencially mac
  84.     //    character codes, while values we are assigning are NeXT character codes).
  85.     //
  86.     ConvertArray[NEWLINE] = CARRIAGERETURN; // Convert line endings
  87.     //    0x8X
  88.     ConvertArray[0x80] = 0xCA;        // (nbspace)next
  89.     ConvertArray[0x81] = 0xCB;        // (Agrave)
  90.     ConvertArray[0x82] = 0xE7;        // (Aacute)
  91.     ConvertArray[0x83] = 0xE5;        // (Acircumflex)
  92.     ConvertArray[0x84] = 0xCC;        // (Atilde)
  93.     ConvertArray[0x85] = 0x80;        // (Adieresis)
  94.     ConvertArray[0x86] = 0x81;        // (Aring)
  95.     ConvertArray[0x87] = 0x82;        // (Ccedilla)
  96.     ConvertArray[0x88] = 0xE9;        // (Egrave)
  97.     ConvertArray[0x89] = 0x83;        // (Eacute)
  98.     ConvertArray[0x8A] = 0xE6;        // (Ecircumflex)
  99.     ConvertArray[0x8B] = 0xE8;        // (Edieresis)
  100.     ConvertArray[0x8C] = 0xED;        // (Igrave)
  101.     ConvertArray[0x8D] = 0xEA;        // (Iacute)
  102.     ConvertArray[0x8E] = 0xEB;        // (Icircumflex)
  103.     ConvertArray[0x8F] = 0xEC;        // (Idieresis)
  104.     //    0x9X
  105.     ConvertArray[0x90] = NullCharacter;    // (Eth)
  106.     ConvertArray[0x91] = 0x84;        // (Ntilde)
  107.     ConvertArray[0x92] = 0xF1;        // (Ograve)
  108.     ConvertArray[0x93] = 0xEE;        // (Oacute)
  109.     ConvertArray[0x94] = 0xEF;        // (Ocircumflex)
  110.     ConvertArray[0x95] = 0xCD;        // (Otilde)
  111.     ConvertArray[0x96] = 0x85;        // (Odieresis)
  112.     ConvertArray[0x97] = 0xF4;        // (Ugrave)
  113.     ConvertArray[0x98] = 0xF2;        // (Uacute)
  114.     ConvertArray[0x99] = 0xF3;        // (Ucircumflex)
  115.     ConvertArray[0x9A] = 0x86;        // (Udieresis)
  116.     ConvertArray[0x9B] = NullCharacter;    // (Yacute)
  117.     ConvertArray[0x9C] = NullCharacter;    // (Thorn)
  118.     ConvertArray[0x9D] = 0xB5;        // (mu)
  119.     ConvertArray[0x9E] = NullCharacter;            // (multiply)
  120.     ConvertArray[0x9F] = 0xD6;        // (divide)
  121.     //    0xAX
  122.     ConvertArray[0xA0] = 0xA9;        // (copyrightserif)
  123.     ConvertArray[0xA1] = 0xC1;        // (exclamdown)
  124.     ConvertArray[0xA2] = 0xA2;        // (cent)
  125.     ConvertArray[0xA3] = 0xA3;        // (sterling)
  126.     ConvertArray[0xA4] = 0xDA;        // (fraction)
  127.     ConvertArray[0xA5] = 0xB4;        // (yen)
  128.     ConvertArray[0xA6] = 0xC4;        // (florin)
  129.     ConvertArray[0xA7] = 0xA4;        // (section)
  130.     ConvertArray[0xA8] = 0xDB;        // (currency)
  131.     ConvertArray[0xA9] = 0x27;        // (quotesingle)
  132.     ConvertArray[0xAA] = 0xD2;        // (quotedblleft)
  133.     ConvertArray[0xAB] = 0xC7;        // (guillemotleft)
  134.     ConvertArray[0xAC] = 0xDC;        // (guilsinglleft)
  135.     ConvertArray[0xAD] = 0xDD;        // (guilsinglright)
  136.     ConvertArray[0xAE] = 0xDE;        // (fi)
  137.     ConvertArray[0xAF] = 0xDF;        // (fl)
  138.     //    0xBX
  139.     ConvertArray[0xB0] = 0xA8;        // (registerserif)
  140.     ConvertArray[0xB1] = 0xD0;        // (endash)
  141.     ConvertArray[0xB2] = 0xA0;        // (dagger)
  142.     ConvertArray[0xB3] = 0xE0;        // (daggerdbl)
  143.     ConvertArray[0xB4] = 0xE1;        // (periodcentered)
  144.     ConvertArray[0xB5] = NullCharacter;    // (brokenbar)
  145.     ConvertArray[0xB6] = 0xA6;        // (paragraph)
  146.     ConvertArray[0xB7] = 0xA5;        // (bullet)
  147.     ConvertArray[0xB8] = 0xE2;        // (quotesinglebase)
  148.     ConvertArray[0xB9] = 0xE3;        // (quotedblbase)
  149.     ConvertArray[0xBA] = 0xD3;        // (quotedblright)
  150.     ConvertArray[0xBB] = 0xC8;        // (guillemotright)
  151.     ConvertArray[0xBC] = 0xC9;        // (elipsis)
  152.     ConvertArray[0xBD] = 0xE4;        // (perthousand)
  153.     ConvertArray[0xBE] = 0xC2;        // (logicalnot)
  154.     ConvertArray[0xBF] = 0xC0;        // (questiondown)
  155.     //    0xCX
  156.     ConvertArray[0xC0] = NullCharacter;            // (onesuperior)
  157.     ConvertArray[0xC1] = 0x60;        // (grave)
  158.     ConvertArray[0xC2] = 0xAB;        // (acute)
  159.     ConvertArray[0xC3] = 0xF6;        // (circumflex)
  160.     ConvertArray[0xC4] = 0xF7;        // (tilde)
  161.     ConvertArray[0xC5] = 0xF8;        // (macron)
  162.     ConvertArray[0xC6] = 0xF9;        // (breve)
  163.     ConvertArray[0xC7] = 0xFA;        // (dotaccent)
  164.     ConvertArray[0xC8] = 0xAC;        // (dieresis)
  165.     ConvertArray[0xC9] = NullCharacter;    // (twosuperior)
  166.     ConvertArray[0xCA] = 0xFB;        // (ring)
  167.     ConvertArray[0xCB] = 0xFC;        // (cedilla)
  168.     ConvertArray[0xCC] = NullCharacter;    // (threesuperior)
  169.     ConvertArray[0xCD] = 0xFD;        // (hungarumlaut)
  170.     ConvertArray[0xCE] = 0xFE;        // (ogonek)
  171.     ConvertArray[0xCF] = 0xFF;        // (caron)
  172.     //    0xDX
  173.     ConvertArray[0xD0] = 0xD1;        // (emdash)
  174.     ConvertArray[0xD1] = 0xB1;        // (plusminus)
  175.     ConvertArray[0xD2] = NullCharacter;    // (onequarter)
  176.     ConvertArray[0xD3] = NullCharacter;    // (onehalf)
  177.     ConvertArray[0xD4] = NullCharacter;    // (threequarters)
  178.     ConvertArray[0xD5] = 0x88;        // (agrave)
  179.     ConvertArray[0xD6] = 0x87;        // (aacute)
  180.     ConvertArray[0xD7] = 0x89;        // (acircumflex)
  181.     ConvertArray[0xD8] = 0x8B;        // (atilde)
  182.     ConvertArray[0xD9] = 0x8A;        // (adieresis)
  183.     ConvertArray[0xDA] = 0x8C;        // (aring)
  184.     ConvertArray[0xDB] = 0x8D;        // (ccedilla)
  185.     ConvertArray[0xDC] = 0x8F;        // (egrave)
  186.     ConvertArray[0xDD] = 0x8E;        // (eacute)
  187.     ConvertArray[0xDE] = 0x90;        // (ecircumflex)
  188.     ConvertArray[0xDF] = 0x91;        // (dieresis)
  189.     //    0xE0
  190.     ConvertArray[0xE0] = 0x93;        // (igrave)
  191.     ConvertArray[0xE1] = 0xAE;        // (AE)
  192.     ConvertArray[0xE2] = 0x92;        // (iacute)
  193.     ConvertArray[0xE3] = 0xBB;        // (ordfeminine)
  194.     ConvertArray[0xE4] = 0x94;        // (icircumflex)
  195.     ConvertArray[0xE5] = 0x95;        // (idieresis)
  196.     ConvertArray[0xE6] = NullCharacter;    // (eth)
  197.     ConvertArray[0xE7] = 0x96;        // (ntilde)
  198.     ConvertArray[0xE8] = NullCharacter;    // (Lslash)
  199.     ConvertArray[0xE9] = 0xAF;        // (Oslash)
  200.     ConvertArray[0xEA] = 0xCE;        // (OE)
  201.     ConvertArray[0xEB] = 0xBC;        // (ordmasculine)
  202.     ConvertArray[0xEC] = 0x98;        // (ograve)
  203.     ConvertArray[0xED] = 0x97;        // (oacute)
  204.     ConvertArray[0xEE] = 0x99;        // (ocircumflex)
  205.     ConvertArray[0xEF] = 0x9B;        // (otilde)
  206.     //    0xF0
  207.     ConvertArray[0xF0] = 0x9A;        // (odieresis)
  208.     ConvertArray[0xF1] = 0xBE;        // (ae)
  209.     ConvertArray[0xF2] = 0x9D;        // (ugrave)
  210.     ConvertArray[0xF3] = 0x9C;        // (uacute)
  211.     ConvertArray[0xF4] = 0x9E;        // (ucircumflex)
  212.     ConvertArray[0xF5] = 0xF5;        // (dotlessi)
  213.     ConvertArray[0xF6] = 0x9F;        // (udieresis)
  214.     ConvertArray[0xF7] = NullCharacter;    // (yacute)
  215.     ConvertArray[0xF8] = NullCharacter;    // (lslash)
  216.     ConvertArray[0xF9] = 0xBF;        // (oslash)
  217.     ConvertArray[0xFA] = 0xCF;        // (oe)
  218.     ConvertArray[0xFB] = 0xA7;        // (germandbls)
  219.     ConvertArray[0xFC] = NullCharacter;    // (thorn)
  220.     ConvertArray[0xFD] = 0xD8;        // (ydieresis)
  221.     ConvertArray[0xFE] = NullCharacter;    // (not assigned)
  222.     ConvertArray[0xFF] = NullCharacter;    // (ascii control char?)
  223.     return self;
  224. }
  225.  
  226.  
  227.  
  228.  
  229. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  230. //    Routine:        ConvertCharacter:
  231. //    Parameters:    a character to be converted
  232. //    Returns:        the converted character
  233. //    Stores:        the character that we are returning.
  234. //    Description:
  235. //        This uses the ConvertArray set up in the initialization to convert
  236. //        a character from the NeXT character set to a Mac char.  It allows for converting
  237. //        single quotes to either Mac style (grave accent and single neuter quote) or to
  238. //        curly mac quotes (not in the lower ascii range)  It returns the converted
  239. //        character and a result code based on its succes.
  240. //    Bugs:
  241. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  242. - (Character) ConvertCharacter: (Character) theCharacter
  243. {
  244.     Character    result;
  245.     Boolean        couldconvert = YES;
  246.     [self ResetResults];
  247.     //
  248.     //    Look up our result in the conversion array.     //
  249.     result = ConvertArray[theCharacter];
  250.     //
  251.     //    If we've been asked to convert ` and ' to nice Mac curly quotes,
  252.     //    rather than ˋ and ', then see if we got a quote, and change the result
  253.     //    appropriately.
  254.     //
  255.     if (UseCurlyQuotes == YES)
  256.     {
  257.         if (theCharacter == 0x27)
  258.             result = 0xD5;        // (quoteright)
  259.         else if (theCharacter == 0x60)
  260.             result = 0xD4;        // (quoteleft)
  261.     }
  262.     //
  263.     //    Alternately, if we got a null back, and we were give (and we don't didn't
  264.     //    pass a null), indicate we could not convet properly.
  265.     //
  266.     if ((result == NullCharacter) &&  (theCharacter != NullCharacter))
  267.     {
  268.         result = theCharacter;
  269.         couldconvert = NO;
  270.     }
  271.     //
  272.     //    Store the result, and return.
  273.     //
  274.     [self    PutCharacter: result Into: FIRST_RESULT];
  275.     if (couldconvert == YES)
  276.         [self    StoreErrorCode: errOK AndText: "Character converted!"];
  277.     else
  278.         [self    StoreErrorCode: errCANTMAPTOONE AndText: "No equivalent standard Macintosh character"];
  279.     return result;
  280. }
  281.  
  282.  
  283. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  284. //    Routine:        ConvertString:WithLength:
  285. //    Parameters:    a pointer to a string of data to be converted
  286. //                the length of the data the poiner poins to.
  287. //    Returns:        a poiner to a new block of data to be converted
  288. //    Stores:        the pointer we are returning
  289. //                the length of the new data
  290. //    Description:
  291. //        This converts the text in the source data area into a new area.
  292. //        This is passed a string of characters.  This then creates a new string,
  293. //        and converts all the source characters from a Macintosh encoding to
  294. //        the destination string.  This differs from ConvertCharacter:, above, int only
  295. //        two ways:  The first is that this processes multiple characters at once.
  296. //        the second is that if it finds a character that's doens't map to a specific
  297. //        alternate character, it will replace it with a multi character string.  E.g.
  298. //        less  than or equal to is replaced with <=  And the apple symbol is just
  299. //        replaced with [apple].  The source string is not altered in any way.  The
  300. //        caller is responsible for disposing of the returned string.
  301. //    Bugs:
  302. //        we don't really check for errors anywhere (not taht there are many oportunities)...
  303. //    History
  304. //        92.12.31    djb    Added a null-character termination to the string.
  305. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  306. - (Pointer) ConvertString: (Pointer) theData WithLength: (Integer) length
  307. {
  308.     Character*    source = (Character*) theData; // getting a better typed ptr.
  309.     Integer        index;
  310.     PositiveInteger    destindex = 0;
  311.     Integer        destsize = length*1.5;
  312.     Integer        replacelength;
  313.     CString        replacement;
  314.     Character*    temp, *dest = (Character*) NewPointer(destsize);
  315.     Character    result;
  316.     [self    ResetResults];
  317.     for (index = 0; index < length; index++)
  318.     {
  319.         //
  320.         //    Look up our result in the conversion array.         //
  321.         result = ConvertArray[source[index]];
  322.         //
  323.         //    If we've been asked to convert ` and ' to nice Mac curly quotes,
  324.         //    rather than ˋ and ', then see if we got a quote, and change the result
  325.         //    appropriately.
  326.         //
  327.         if (UseCurlyQuotes == YES)
  328.         {
  329.             if (source[index] == 0x27)
  330.                 result = 0xD5;        // (quoteright)
  331.             else if (source[index] == 0x60)
  332.                 result = 0xD4;        // (quoteleft)
  333.         }
  334.         //
  335.         //    If our result is not a null (or if we passed a null), stick the result into
  336.         //    the destination space.  increment the space if necessary.
  337.         //
  338.         if ((result != NullCharacter) ||  (source[index] == NullCharacter))
  339.         {
  340.             if (destindex >= destsize)
  341.             {
  342.                 temp = NewPointer(destsize +512);
  343.                 memcpy(temp, dest, destsize);
  344.                 FreePointer(dest);
  345.                 dest = temp;
  346.                 destsize += 512;
  347.             }
  348.             dest[destindex] = result;
  349.             destindex++;
  350.         }
  351.         else
  352.         {
  353.             //
  354.             //    We evidently got a null back, telling us 'yo! I can't convert this to
  355.             //    a different single character'.  So, now we determine which it was, and
  356.             //    determine what string to use in its place.  Generally, we use the PS
  357.             //    name for the character in []'s.
  358.             //
  359.             switch (source[index])
  360.             {
  361.                 case 0x90:            // (Eth)
  362.                     replacement = "[Eth]";
  363.                     break;
  364.                 case 0x9B:            // (Yacute)
  365.                     replacement = "[Yacute]";
  366.                     break;
  367.                 case 0x9C:            // (Thorn)
  368.                     replacement = "[Thorn]";
  369.                     break;
  370.                 case 0x9E:            // (multiply)
  371.                     replacement = "[multiply]";
  372.                     break;
  373.                 case 0xB5:            // (brokenbar)
  374.                     replacement = "[brokenbar]";
  375.                     break;
  376.                 case 0xC0:            // (onesuperior)
  377.                     replacement = "[onesuperior]";
  378.                     break;
  379.                 case 0xC9:            // (twosuperior)
  380.                     replacement = "[twosuperior]";
  381.                     break;
  382.                 case 0xCC:            // (threesuperior)
  383.                     replacement = "[threesuperior]";
  384.                     break;
  385.                 case 0xD2:            // (onequarter)
  386.                     replacement = "[onequarter]";
  387.                     break;
  388.                 case 0xD3:            // (onehalf)
  389.                     replacement = "[onehalf]";
  390.                     break;
  391.                 case 0xD4:            // (threequarters)
  392.                     replacement = "[threequarters]";
  393.                     break;
  394.                 case 0xE6:            // (eth)
  395.                     replacement = "[eth]";
  396.                     break;
  397.                 case 0xE8:            // (Lslash)
  398.                     replacement = "[Lslash]";
  399.                     break;
  400.                 case 0xF7:            // (yacute)
  401.                     replacement = "[yacute]";
  402.                     break;
  403.                 case 0xF8:            // (lslash)
  404.                     replacement = "[lslash]";
  405.                     break;
  406.                 case 0xFC:            // (thorn)
  407.                     replacement = "[thorn]";
  408.                     break;
  409.                 case 0xFE:            // (not assigned)
  410.                     replacement = "[not defined]";
  411.                     break;
  412.                 case 0xFF:            // (ascii control char?)
  413.                     replacement = "[ascii control char]";
  414.                     break;                default:
  415.                     replacement = "[[THERE IS A BUG IN THE PROIGRAM (no joke)]]";
  416.                     break;
  417.             }
  418.             //
  419.             //    With a string in hand to use now, get it's length, and assure that we
  420.             //    have space to store it (if not, increment the memory block's size).
  421.             //    copy the string into the output memory space, and continue.
  422.             //
  423.             replacelength = strlen(replacement);
  424.             if ( (destindex+replacelength) >= destsize)
  425.             {
  426.                 temp = NewPointer(destsize + 512);
  427.                 memcpy(temp, dest, destsize);
  428.                 FreePointer(dest);
  429.                 dest = temp;
  430.                 destsize = destsize + 512;
  431.             }
  432.             memcpy(&dest[destindex], replacement, strlen(replacement));
  433.             destindex += replacelength;
  434.         }
  435.     }
  436.     //
  437.     //    Added, so that the block of memory returned is also null terminated.
  438.     //
  439.     if (destindex >= destsize)
  440.     {
  441.         temp = NewPointer(destsize +512);
  442.         memcpy(temp, dest, destsize);
  443.         FreePointer(dest);
  444.         dest = temp;
  445.         destsize += 512;
  446.     }
  447.     dest[destindex] = EndOfCString;
  448.     //
  449.     //    Store the result, and return.  (note that destindex always ends up pointing to
  450.     //    the next byte to be used, and thus is also a count of the total number of bytes
  451.     //    in the dest string.
  452.     //
  453.     [self    StorePointer: dest];
  454.     [self    PutPositiveInteger: destindex Into: SECOND_RESULT];
  455.     [self    StoreErrorCode: errOK AndText: "Nothing could go wrong (pathetic program)!"];
  456.     return dest;
  457. }
  458.  
  459.  
  460. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  461. //    Routine:        ConvertSingleQuotes:
  462. //    Parameters:    a boolean value
  463. //    Returns:        self
  464. //    Stores:        none
  465. //    Description:
  466. //        This simply allows the user to toggle whether they want to do convert single
  467. //        quotes to pretty curly quotes on the Mac or not.
  468. //    Bugs:
  469. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  470. - ConvertSingleQuotes:  (Boolean) useCurlyQuotes
  471. {
  472.     UseCurlyQuotes = useCurlyQuotes;
  473.     return self;
  474. }
  475. @@end
  476. @
  477.  
  478.  
  479. 1.1
  480. log
  481. @Sun Jan 10 15:08:29 PST 1993
  482. @
  483. text
  484. @d7 6
  485. a12 3
  486.     This is $Revision: 1.4 $ of this file
  487.     It was last modifiFed by $Author: death $ on $Date: 92/04/05 22:51:36 $
  488.      $Log:    $
  489. @
  490.